package com.liuzy.util;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

/**
 * RSA非对称加密
 * 
 * @author liuzy
 * @version 2015年5月22日
 */
public class RSA {

	static KeyPairGenerator keyPairGenerator = null;
	static KeyFactory kf = null;
	static Cipher cipher = null;
	static {
		try {
			keyPairGenerator = KeyPairGenerator.getInstance("RSA");
			kf = KeyFactory.getInstance("RSA");
			cipher = Cipher.getInstance("RSA");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static Map<String, String> createKey() {
		Map<String, String> keyMap = new HashMap<String, String>();

		SecureRandom secureRandom = new SecureRandom(new Date().toString().getBytes());
		keyPairGenerator.initialize(1024, secureRandom);
		KeyPair keyPair = keyPairGenerator.generateKeyPair();
		PublicKey publicKey = keyPair.getPublic();
		PrivateKey privateKey = keyPair.getPrivate();

		/*
		 * 输出到文件 FileOutputStream fos1 = new
		 * FileOutputStream("d:/key/publicKey"); FileOutputStream fos2 = new
		 * FileOutputStream("d:/key/privateKey");
		 * fos1.write(publicKey.getEncoded());
		 * fos2.write(privateKey.getEncoded()); fos1.close(); fos2.close();
		 */

		keyMap.put("publicKey", Util.bytesToHexStr(publicKey.getEncoded()));
		keyMap.put("privateKey", Util.bytesToHexStr(privateKey.getEncoded()));

		return keyMap;
	}

	public static String encode(String msg, String pubKey) {
		try {
			byte[] pubKeyBytes = Util.hexStrToBytes(pubKey);

			X509EncodedKeySpec spec = new X509EncodedKeySpec(pubKeyBytes);
			PublicKey publicKey = kf.generatePublic(spec);

			cipher.init(Cipher.ENCRYPT_MODE, publicKey);
			byte[] bytes = cipher.doFinal(msg.getBytes());
			return Util.bytesToHexStr(bytes);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String decode(String hexMsg, String priKey) {
		try {
			byte[] priKeyBytes = Util.hexStrToBytes(priKey);

			PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(priKeyBytes);
			PrivateKey privateKey = kf.generatePrivate(spec);

			cipher.init(Cipher.DECRYPT_MODE, privateKey);
			byte[] bytes = cipher.doFinal(Util.hexStrToBytes(hexMsg));
			return new String(bytes);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

}
